<?php

declare(strict_types=1);

namespace MultiWorker\Logger\Channel;

use MultiWorker\Logger\Channel;
use MultiWorker\Logger\LoggerLevel;

class Console extends Channel
{
    /**
     * availableForegroundColors
     *
     * @var array
     */
    protected static $availableForegroundColors = [
        'black'   => ['set' => 30, 'unset' => 39],
        'red'     => ['set' => 31, 'unset' => 39],
        'green'   => ['set' => 32, 'unset' => 39],
        'yellow'  => ['set' => 33, 'unset' => 39],
        'blue'    => ['set' => 34, 'unset' => 39],
        'magenta' => ['set' => 35, 'unset' => 39],
        'cyan'    => ['set' => 36, 'unset' => 39],
        'white'   => ['set' => 37, 'unset' => 39],
    ];

    /**
     * availableBackgroundColors
     *
     * @var array
     */
    protected static $availableBackgroundColors = [
        'black'   => ['set' => 40, 'unset' => 49],
        'red'     => ['set' => 41, 'unset' => 49],
        'green'   => ['set' => 42, 'unset' => 49],
        'yellow'  => ['set' => 43, 'unset' => 49],
        'blue'    => ['set' => 44, 'unset' => 49],
        'magenta' => ['set' => 45, 'unset' => 49],
        'cyan'    => ['set' => 46, 'unset' => 49],
        'white'   => ['set' => 47, 'unset' => 49],
    ];

    /**
     * 写日志
     *
     * @param string $message
     * @param mixed $level
     * @param array $context
     * @return void
     */
    public function write ($message,$level,array $context = [])
    {
        $content = $this->formatContent($message,$level,$context);
        if (!$this->isApartLevel($level)) {
            return;
        }
        $this->echo($level,$content);
    }

    /**
     * 打印消息
     *
     * @param string $level
     * @param string $content
     * @return void
     */
    public function echo ($level,$content)
    {
        [$setCodes,$unsetCodes] = $this->getStyleCodes($level);
        $styleText = $this->getStyleText($content,$setCodes,$unsetCodes);
        echo $styleText;
    }
    /**
     * 获取样式code.
     *
     * @param string $level
     * @return array
     */
    protected function getStyleCodes ($level): array
    {
        $codes = ['set' => [],'unset' => []];
        switch ($level) {
            case LoggerLevel::DEBUG:
                $codes['set'][] = static::$availableForegroundColors['green']['set'];
                $codes['unset'][] = static::$availableForegroundColors['green']['unset'];
                break;
            case LoggerLevel::INFO:
                $codes['set'][] = static::$availableForegroundColors['cyan']['set'];
                $codes['unset'][] = static::$availableForegroundColors['cyan']['unset'];
                break;
            case LoggerLevel::WARNING:
                $codes['set'][] = static::$availableForegroundColors['yellow']['set'];
                $codes['unset'][] = static::$availableForegroundColors['yellow']['unset'];
                break;
            case LoggerLevel::ERROR:
                $codes['set'][] = static::$availableForegroundColors['red']['set'];
                $codes['unset'][] = static::$availableForegroundColors['red']['unset'];
                break;
            case LoggerLevel::CRITICAL:
                $codes['set'][] = static::$availableForegroundColors['blue']['set'];
                $codes['unset'][] = static::$availableForegroundColors['blue']['unset'];
                break;
            case LoggerLevel::ALERT:
                $codes['set'][] = static::$availableForegroundColors['magenta']['set'];
                $codes['unset'][] = static::$availableForegroundColors['magenta']['unset'];
                break;
            case LoggerLevel::EMERGENCY:
                $codes['set'][] = static::$availableBackgroundColors['red']['set'];
                $codes['unset'][] = static::$availableBackgroundColors['red']['unset'];
                $codes['set'][] = static::$availableForegroundColors['white']['set'];
                $codes['unset'][] = static::$availableForegroundColors['white']['unset'];
                break;
            default:
                $codes['set'][] = static::$availableForegroundColors['black']['set'];
                $codes['unset'][] = static::$availableForegroundColors['black']['unset'];
                break;
        }
        return [$codes['set'],$codes['unset']];
    }

    /**
     * 获取带样式的文本
     *
     * @param string $content
     * @param array  $setCodes
     * @param array  $unsetCodes
     * @return string
     */
    protected function getStyleText ($content,$setCodes,$unsetCodes): string
    {
        return sprintf("\033[%sm%s\033[%sm", implode(';', $setCodes), $content, implode(';', $unsetCodes));
    }
}